package com.bill99.rpc.registry.support;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.bill99.rpc.registry.NotifyListener;
import com.bill99.rpc.registry.Registry;
import com.bill99.rpc.registry.url.ReferenceUrl;
import com.bill99.rpc.registry.url.RegistryUrl;
import com.bill99.rpc.registry.url.ServiceUrl;

/**
 * @author sheng.zhang
 * 
 */
public abstract class AbstractRegistry implements Registry {

	protected final Logger logger = LoggerFactory.getLogger(getClass());

	protected RegistryUrl registryUrl;

	public AbstractRegistry(RegistryUrl registryUrl) {
		this.registryUrl = registryUrl;
	}

	@Override
	public void register(ServiceUrl serviceUrl) {
		try {
			logger.info("to registry service, service url: [{}]",serviceUrl);
			doRegister(serviceUrl);
		} catch (Exception e) {
			logger.error("Failed to register " + serviceUrl
					+ ", waiting for retry, cause: " + e.getMessage(), e);
		}
	}

	@Override
	public void unregister(ServiceUrl serviceUrl) {
		try {
			logger.info("to unregistry service, service url: [{}]",serviceUrl);
			doUnregister(serviceUrl);
		} catch (Exception e) {
			logger.error("Failed to uregister " + serviceUrl
					+ ", waiting for retry, cause: " + e.getMessage(), e);
		}
	}

	@Override
	public void subscribe(ReferenceUrl referenceUrl, NotifyListener listener) {
		try {
			logger.info("to subscribe service, reference url: [{}]",referenceUrl);
			doSubscribe(referenceUrl, listener);
		} catch (Exception e) {
			logger.error("Failed to subscribe " + referenceUrl
					+ ", waiting for retry, cause: " + e.getMessage(), e);
		}
	}

	@Override
	public void unsubscribe(ReferenceUrl referenceUrl, NotifyListener listener) {
		try {
			logger.info("to unsubscribe service, reference url: [{}]",referenceUrl);
			doUnsubscribe(referenceUrl, listener);
		} catch (Exception e) {
			logger.error("Failed to unsubscribe " + referenceUrl
					+ ", waiting for retry, cause: " + e.getMessage(), e);
		}
	}

	@Override
	public List<ServiceUrl> lookup(ReferenceUrl referenceUrl) {
		try {
			logger.info("to lookup service, reference url: [{}]",referenceUrl);
			return doLookup(referenceUrl);
		} catch (Exception e) {
			logger.error("Failed to lookup " + referenceUrl
					+ ", waiting for retry, cause: " + e.getMessage(), e);
		}
		return new ArrayList<ServiceUrl>();
	}

	// ==== 模板方法 ====

	protected abstract void doRegister(ServiceUrl serviceUrl);

	protected abstract void doUnregister(ServiceUrl serviceUrl);

	protected abstract void doSubscribe(ReferenceUrl referenceUrl,
			NotifyListener listener);

	protected abstract void doUnsubscribe(ReferenceUrl referenceUrl,
			NotifyListener listener);

	protected abstract List<ServiceUrl> doLookup(ReferenceUrl referenceUrl);

}